#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
数据大屏相关的请求&响应 Schema
"""

from datetime import datetime
from decimal import Decimal
from typing import Optional, List, Dict, Any

from pydantic import BaseModel, Field, validator


# ==================== 请求参数模型 ====================
class DashboardQueryRequest(BaseModel):
	"""数据大屏通用查询参数"""
	province_code: Optional[str] = Field(None, description="省编码")
	city_code: Optional[str] = Field(None, description="市编码")
	area_code: Optional[str] = Field(None, description="区编码")
	start_time: Optional[datetime] = Field(None, description="开始时间")
	end_time: Optional[datetime] = Field(None, description="结束时间")
	station_id: Optional[int] = Field(None, description="台区ID")
	force_refresh: bool = Field(False, description="是否强制刷新缓存")

	@property
	def region_prefix(self) -> Optional[str]:
		"""获取区域编码前缀"""
		from app.crud.alarm_crud import safe_slice
		return (
				safe_slice(self.area_code, 6) or
				safe_slice(self.city_code, 4) or
				safe_slice(self.province_code, 2)
		)


class HighLoadStationQueryRequest(BaseModel):
	"""高负载台区查询参数"""
	limit: int = Field(10, ge=1, le=50, description="返回条数限制")
	sort_by: str = Field("load_percentage", description="排序字段: load_percentage|alarm_count")
	order: str = Field("desc", description="排序方向: asc|desc")
	force_refresh: bool = Field(False, description="是否强制刷新缓存")

	@validator('sort_by')
	def validate_sort_by(cls, v):
		allowed = ['load_percentage', 'alarm_count', 'load_kw']
		if v not in allowed:
			return 'load_percentage'
		return v

	@validator('order')
	def validate_order(cls, v):
		return v.lower() if v.lower() in ['asc', 'desc'] else 'desc'


class RecentAlertsQueryRequest(BaseModel):
	"""最近告警查询参数"""
	limit: int = Field(20, ge=1, le=100, description="返回条数")
	force_refresh: bool = Field(False, description="是否强制刷新缓存")


# ==================== KPI统计接口 ====================
class LoadEnergyMetricsResponse(BaseModel):
	"""负荷与供电量指标响应模型"""
	total_load_mw: float = Field(..., description="当前总负荷(MW)")
	total_energy_kwh: float = Field(..., description="今日累计供电量(万kWh)")
	load_change_percent: float = Field(..., description="与昨日同比变化(%)")

	# 线损数据
	total_loss_rate: float = Field(0.0, description="总线损率(%)")
	total_loss_kwh: float = Field(0.0, description="总损耗电量(kWh)")

	# 分相电表统计
	phase_a_meter_count: int = Field(0, description="A相电表总数")
	phase_b_meter_count: int = Field(0, description="B相电表总数")
	phase_c_meter_count: int = Field(0, description="C相电表总数")
	phase_three_count: int = Field(0, description="三相RTU设备数量(dev_rtu)")

	updated_at: datetime = Field(..., description="数据更新时间")


class KPIMetricsResponse(BaseModel):
	"""KPI指标响应模型（不含负荷与供电量、线损）"""
	# 设备统计
	station_total: int = Field(..., description="台区总数")
	station_online: int = Field(..., description="在线台区数")
	station_online_rate: float = Field(..., description="台区在线率(%)")

	box_total: int = Field(..., description="电箱总数")
	box_online: int = Field(..., description="在线电箱数")
	box_online_rate: float = Field(..., description="电箱在线率(%)")

	rtu_total: int = Field(..., description="RTU总数")
	rtu_online: int = Field(..., description="在线RTU数")
	rtu_online_rate: float = Field(..., description="RTU在线率(%)")

	meter_abnormal: int = Field(..., description="异常电表数")
	meter_total: int = Field(..., description="电表数")
	meter_abnormal_rate: float = Field(..., description="电表异常率(%)")

	# 告警统计
	alarm_total: int = Field(..., description="未处理告警总数")
	alarm_critical: int = Field(..., description="严重告警数")
	alarm_warning: int = Field(..., description="一般告警数")
	alarm_info: int = Field(..., description="提示告警数")

	# 按区域过滤的统计
	open_alarm_count: int = Field(..., description="区域内未处理告警数量")
	pending_work_order_count: int = Field(..., description="区域内未完成工单数量")

	# 供电可靠性
	power_reliability: Decimal = Field(..., description="供电可靠性(%)")

	# 更新时间
	updated_at: datetime = Field(..., description="数据更新时间")


# ==================== 高负载台区列表接口 ====================
class StationLoadItem(BaseModel):
	"""台区负载项"""
	id: int = Field(..., description="台区ID")
	name: str = Field(..., description="台区名称")
	code: str = Field(..., description="台区编码")
	load_kw: float = Field(..., description="实时负荷(kW)")
	capacity_kva: Optional[int] = Field(None, description="配变容量(kVA)")
	load_percentage: float = Field(..., description="负荷率(%)")
	alarm_count: int = Field(..., description="告警数量")
	status: str = Field(..., description="状态: 正常|预警|严重")
	status_color: str = Field(..., description="状态颜色: green|yellow|red")
	manager_code: Optional[str] = Field(None, description="负责人工号")
	updated_at: datetime = Field(..., description="数据更新时间")


class HighLoadStationResponse(BaseModel):
	"""高负载台区列表响应"""
	stations: List[StationLoadItem] = Field(..., description="台区列表")
	total_count: int = Field(..., description="符合条件的总数")
	updated_at: datetime = Field(..., description="数据更新时间")


# ==================== 实时告警流水接口 ====================
class AlertStreamItem(BaseModel):
	"""告警流水项"""
	id: int = Field(..., description="告警ID")
	time: Optional[str] = Field(None, description="告警时间(HH:MM:SS)")
	device_code: str = Field(..., description="设备名称")
	device_type: str = Field(..., description="设备类型: 台区|电箱|RTU|电表")
	alarm_type: str = Field(..., description="告警类型")
	severity: int = Field(..., description="告警级别: 1提示 2一般 3严重")
	severity_label: str = Field(..., description="告警级别标签")
	current_value: Optional[float] = Field(None, description="当前值")
	threshold: Optional[float] = Field(None, description="阈值")
	unit: Optional[str] = Field(None, description="单位")
	message: Optional[str] = Field(None, description="格式化告警消息")
	raised_at: datetime = Field(..., description="告警产生时间")


class RecentAlertsResponse(BaseModel):
	"""最近告警响应"""
	alerts: List[AlertStreamItem] = Field(..., description="告警列表")
	total_count: int = Field(..., description="总告警数")
	updated_at: datetime = Field(..., description="数据更新时间")


# ==================== 告警统计接口 ====================
class AlarmStatsResponse(BaseModel):
	"""告警统计响应"""
	# 按级别统计
	critical_count: int = Field(..., description="严重告警数")
	warning_count: int = Field(..., description="一般告警数")
	info_count: int = Field(..., description="提示告警数")

	# 按类型统计
	type_stats: List[Dict[str, Any]] = Field(..., description="按类型统计")

	# 24小时趋势
	hourly_trend: List[Dict[str, Any]] = Field(..., description="24小时告警趋势")

	updated_at: datetime = Field(..., description="数据更新时间")


# ==================== WebSocket消息格式 ====================
class WebSocketMessage(BaseModel):
	"""WebSocket消息格式"""
	type: str = Field(..., description="消息类型: alert|kpi_update|station_update")
	data: Dict[str, Any] = Field(..., description="消息数据")
	timestamp: datetime = Field(..., description="消息时间戳")


class AlertWebSocketData(BaseModel):
	"""告警WebSocket数据"""
	alert: AlertStreamItem = Field(..., description="告警信息")
	action: str = Field(..., description="动作: new|update|close")
